package com.qf.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.entity.Result;
import com.qf.utils.JwtUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * 这个过滤器，会去处理/login的请求，根据用户提交的username和password进行登录验证
 */
public class FormLoginFilter extends UsernamePasswordAuthenticationFilter {

    public FormLoginFilter(AuthenticationManager authenticationManager){
        super(authenticationManager);
    }
    /**
     * 当登录验证通过后，回调的方法
     * 我们需要在这个方法中，向浏览器响应jwt字符串
     * @param request
     * @param response
     * @param chain
     * @param authResult
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        //向浏览器响应的jwt应该包含：username + roles。如果还有其他数据需求，直接添加在载荷部分
        User user = (User) authResult.getPrincipal();
        String username = user.getUsername();
        List<String> roles = new ArrayList<>();
        Collection<GrantedAuthority> authorities = user.getAuthorities();
        if (authorities != null){
            for (GrantedAuthority authority : authorities) {
                String authStr = authority.getAuthority(); //ROLE_P1  ROLE_P2
                roles.add(authStr);
            }
        }

        //将username和roles封装到map集合
        Map map = new HashMap();
        map.put("username",username);
        map.put("roles",roles);

        //生成jwt
        String token = JwtUtils.createToken(map, username);

        //将token响应到浏览器
        Result result = Result.success(token);
        ObjectMapper om = new ObjectMapper();
        String json = om.writeValueAsString(result);
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(json);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        //在这个方法中，需要向前端项目中响应一个未登录的信息
        Result result = Result.noLogin("用户名或密码错误");
        ObjectMapper om = new ObjectMapper();
        String json = om.writeValueAsString(result);

        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(json);
    }
}
